package com.cloud.flowbusdemo.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.StringRes;

import com.cloud.flowbusdemo.R;
import com.cloud.flowbusdemo.app.App;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Field;

/**
 * @auth: njb
 * @date: 2024/10/11 23:19
 * @desc: 描述
 */
public class ToastUtils {
    private static final String TAG = ToastUtils.class.getName();
    private static boolean sIsHookFieldInit = false;
    private static final String FIELD_NAME_TN = "mTN";
    private static final String FIELD_NAME_HANDLER = "mHandler";

    private static void showToast(final Context context, final CharSequence text, final int duration) {
        ToastRunnable toastRunnable = new ToastRunnable(context, text, duration);
        if (context instanceof Activity) {
            final Activity activity = (Activity) context;
            if (!activity.isFinishing()) {
                activity.runOnUiThread(toastRunnable);
            }
        } else {
            Handler handler = new Handler(context.getMainLooper());
            handler.post(toastRunnable);
        }
    }

    public static void shortToast(String msg) {
        showToast(App.Companion.getInstance(), msg, Toast.LENGTH_SHORT);
    }

    public static void shortToast(@StringRes int resId) {
        showToast(App.Companion.getInstance(), App.Companion.getInstance().getText(resId),
                Toast.LENGTH_SHORT);
    }

    public static void longToast(String msg,int duration) {
        showToast(App.Companion.getInstance(), msg, duration);
    }

    public static void longToast(@StringRes int resId,int duration) {
        showToast(App.Companion.getInstance(), App.Companion.getInstance().getText(resId),
                duration);
    }

    @SuppressLint("SoonBlockedPrivateApi")
    private static void hookToast(Toast toast) {
        try {
            Field sField_TN = null, sField_TN_Handler = null;
            Log.d("hzyHook", "hook flag1 = " + sIsHookFieldInit);
            if (!sIsHookFieldInit) {
                sField_TN = Toast.class.getDeclaredField(FIELD_NAME_TN);
                sField_TN.setAccessible(true);
                sField_TN_Handler = sField_TN.getType().getDeclaredField(FIELD_NAME_HANDLER);
                sField_TN_Handler.setAccessible(true);
                sIsHookFieldInit = true;
            }
            if (sField_TN != null) {
                Object tn = sField_TN.get(toast);
                Handler originHandler = (Handler) sField_TN_Handler.get(tn);
                sField_TN_Handler.set(tn, new SafelyHandlerWrapper(originHandler));
            }
            Log.d("hzyHook", "hook flag2 = " + sIsHookFieldInit);
        } catch (Exception e) {
            Log.e(TAG, "Hook toast exception=" + e);
            Log.d("hzyHook", "hook flag3 = " + sIsHookFieldInit);
        }
    }

    private static class ToastRunnable implements Runnable {
        private Context context;
        private CharSequence text;
        private int duration;

        public ToastRunnable(Context context, CharSequence text, int duration) {
            this.context = context;
            this.text = text;
            this.duration = duration;
        }

        @Override
        public void run() {
            //使用布局加载器，将编写的toast_layout布局加载进来
            View view = LayoutInflater.from(context).inflate(R.layout.layout_custom_toast, null);
            //获取TextView
            TextView title = view.findViewById(R.id.toast_tv);
            //设置显示的内容
            title.setText(text);
            Toast mToast = new Toast(context);
            //设置Toast要显示的位置，水平居中并在底部，X轴偏移0个单位，Y轴偏移70个单位，
            mToast.setGravity(Gravity.CENTER, 0, 70);
            //设置显示时间
            mToast.setDuration(duration);
            mToast.setView(view);
            hookToast(mToast);
            mToast.show();
        }
    }

    private static class SafelyHandlerWrapper extends Handler {
        private final Handler originHandler;

        public SafelyHandlerWrapper(Handler originHandler) {
            this.originHandler = originHandler;
        }

        @Override
        public void dispatchMessage(@NotNull Message msg) {
            try {
                super.dispatchMessage(msg);
            } catch (Exception e) {
                Log.e(TAG, "Catch system toast exception:" + e);
            }
        }

        @Override
        public void handleMessage(@NotNull Message msg) {
            if (originHandler != null) {
                originHandler.handleMessage(msg);
            }
        }
    }
}
